package Hello

import scala.util.control._

object Helloworld {

  def main(args: Array[String]){
  /*  
    val fun1 = (x:Int, y:Int) => x + y
    val helloPrint = () => println("Hello World")
    
    val v1 = fun1(10, 20)
    
    println("Result: " + v1)
    
    helloPrint()
*/
    /*
    println(querry(add10(5), 10))
    
    hel
    
    */
    
    Function.paramDefault(100)
    
    
  }
  
  def add10(x:Int)(y:Int) = x + 10 + y
  
  def querry(f1:Int => Int, x:Int) = f1(x) + 100
  
  def hel() = {println("Hello")}
  
  def callByName() = println("Hello world")
}


class Decorator(left: String, right: String) {
	def layout[A](x: A) = left + x.toString() + right
}

class HigherOrderFunction(){
  
  println(apply(add, 5, 10))
  println(apply(sub, 5, 10))
  
  def apply(f: (Int, Int) => Int, v1: Int, v2: Int) = f(v1, v2)
  
  def add(x:Int, y:Int) = x + y
  def sub(x:Int, y:Int) = x - y
  
  def apply1(f:() => Int, v1: Int, v2: Int) = f()
}

// Demo sử dụng for
object For{
  // Dùng to
  def to(): Unit = {
    var i = 0
    
    for(i <- 1 to 10 if i != 5){
      println(i)
    }
  }
  
  // Dùng until
  def until(): Unit = {
    var i = 0;
    
    for(i <- 1 until 10)
    {
      println(i)
    }
  }
  
  // Dùng List và filter
  def filterList(): Unit = {
    val list = List(1,2,3,4,5,6,7,8,9,10)
    var i = 0
    
    for(i <- list if i % 2 == 0; if i != 4)
    {
      println(i)
    }
  }
  
  // Dùng yield để lấy kết quả của for lưu vào 1 biến khác
  def _yield(): Unit = {
     var i = 0
     
     var list = List(1,2,3,4,5,6,7,8,9,10)
     var result = for(i <- list if i % 2 == 0) yield i
     
     for(i <- result)
     {
       println(i)
     }
  }
  
  // Dùng Break
  def break(): Unit = {
    var i = 0
    val break = new Breaks
    val list = List(1,2,3,4,5,6,7,8,9,10)
    
    break.breakable{
      for(i <- list)
      {
        println(i)
        if(i == 7) break.break
      }
    }
  }
}

// Demo sử dụng function
object Function{
  
  def arguments(x: Int, strParams:String*): Any = {
    var str:String = ""
    var s = ""
      
    for(s <- strParams)
    {
      str += " " + s
    }
    
    println("Int:" + x + " - " + str)
  }
  
  def paramDefault(x: Int=5, y: Int=7) = {
    println(s"x: $x - y: $y")	// String format
  }
}
